package com.supermarket.manage.business.outstock.service;

import com.alibaba.fastjson.JSON;
import com.supermarket.manage.common.constant.StockConstant;
import com.supermarket.manage.common.dto.CodeStatus;
import com.supermarket.manage.common.dto.PageBean;
import com.supermarket.manage.common.dto.ResponseResult;
import com.supermarket.manage.common.dto.prod.request.ProdPageParams;
import com.supermarket.manage.common.dto.prod.response.ProductDto;
import com.supermarket.manage.common.dto.stock.request.StockProdParams;
import com.supermarket.manage.common.dto.stock.response.OutProdDto;
import com.supermarket.manage.common.utils.BigDecimalUtil;
import com.supermarket.manage.provider.api.product.ProductService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author Faxon
 * @version 1.0
 * @date 2020-03-16 18:01
 **/
@Service
public class OutstockProdService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Reference(version = "1.0.0")
    private ProductService productService;

    /**
     * 获取商品分页列表
     *
     * @param params
     * @param prefix
     * @return
     */
    public ResponseResult<PageBean<OutProdDto>> getAllProd(StockProdParams<OutProdDto> params, String prefix) {
        String redisKey = getRedisKey(params, prefix);
        if (redisKey.startsWith("参数错误")) {
            return new ResponseResult<>(CodeStatus.ILLEGAL_REQUEST, redisKey);
        }
        //获取分页数据
        ProdPageParams pageParams = new ProdPageParams();
        pageParams.setPage(params.getPage());
        pageParams.setSize(params.getSize());
        pageParams.setBuyerId(params.getBuyerId());
        pageParams.setPname(params.getPname());
        pageParams.setCid(params.getCid());
        PageBean<ProductDto> pageList = productService.getProdPageList(pageParams);
        if (pageList != null && pageList.getDataList() != null && pageList.getDataList().size() > 0) {
            List<OutProdDto> data = new ArrayList<>();
            Set<String> addedPids = redisTemplate.<String, String>opsForHash().keys(redisKey);
            pageList.getDataList().forEach(p -> {
                OutProdDto dto = new OutProdDto();
                dto.setPid(p.getPid());
                dto.setPnumber(BigDecimalUtil.getNumber(new BigDecimal("0"), 2));
                dto.setSubtotal(BigDecimalUtil.getNumber(new BigDecimal("0"), 2));
                dto.setPname(p.getPname());
                dto.setUnitName(p.getUnitName());
                dto.setPic(p.getPic());
                dto.setCostPrice(p.getCostPrice());
                dto.setSalePrice(p.getSalePrice());
                dto.setVipPrice(p.getVipPrice());
                dto.setFirstCname(p.getFirstCname());
                dto.setSecondCname(p.getSecondCname());
                dto.setThirdCname(p.getThirdCname());
                if (addedPids.contains(p.getPid())) {
                    dto.setGray(Boolean.TRUE);
                } else {
                    dto.setGray(Boolean.FALSE);
                }
                data.add(dto);
            });
            PageBean<OutProdDto> result = new PageBean<>(pageList.getPage(), pageList.getSize(), data, pageList.getTotal());
            return new ResponseResult<>(CodeStatus.OK, "查询成功", result);
        }
        return new ResponseResult<>(CodeStatus.OK, "查询成功", null);
    }

    /**
     * 获取购物车商品
     *
     * @param params
     * @param prefix
     * @return
     */
    public ResponseResult<List<OutProdDto>> getAddedProd(StockProdParams<OutProdDto> params, String prefix) {
        String redisKey = getRedisKey(params, prefix);
        if (redisKey.startsWith("参数错误")) {
            return new ResponseResult<>(CodeStatus.ILLEGAL_REQUEST, redisKey);
        }
        List<OutProdDto> outProdDtos = new ArrayList<>();
        List<String> values = redisTemplate.<String, String>opsForHash().values(redisKey);
        values.forEach(s -> {
            OutProdDto outProdDto = JSON.parseObject(s, OutProdDto.class);
            outProdDtos.add(outProdDto);
        });
        return new ResponseResult<>(CodeStatus.OK, "查询成功", outProdDtos);
    }

    /**
     * 添加商品到购物车
     *
     * @param params
     * @param prefix
     * @return
     */
    public ResponseResult<Void> addOutstockProd(StockProdParams<OutProdDto> params, String prefix) {
        String redisKey = getRedisKey(params, prefix);
        if (redisKey.startsWith("参数错误")) {
            return new ResponseResult<>(CodeStatus.ILLEGAL_REQUEST, redisKey);
        }
        List<OutProdDto> prodList = params.getProdList();
        BoundHashOperations<String, String, String> ops = redisTemplate.<String, String>boundHashOps(redisKey);
        Map<String, String> map = new HashMap<>(prodList.size());
        prodList.forEach(p -> {
            p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
            map.put(p.getPid(), JSON.toJSONString(p));
        });
        if (map.size() > 0) {
            ops.putAll(map);
            ops.expire(1, TimeUnit.HOURS);
        }
        return new ResponseResult<>(CodeStatus.OK, "添加成功");
    }

    /**
     * 更新购物车商品
     *
     * @param params
     * @param prefix
     * @return
     */
    public ResponseResult<Void> updateProd(StockProdParams<OutProdDto> params, String prefix) {
        String redisKey = getRedisKey(params, prefix);
        if (redisKey.startsWith("参数错误")) {
            return new ResponseResult<>(CodeStatus.ILLEGAL_REQUEST, redisKey);
        }
        BoundHashOperations<String, String, String> ops = redisTemplate.<String, String>boundHashOps(redisKey);
        String json = ops.get(params.getPid());
        if (StringUtils.isBlank(json)) {
            return new ResponseResult<>(CodeStatus.FAIL, "修改失败，请刷新页面");
        }
        OutProdDto outProdDto = JSON.parseObject(json, OutProdDto.class);
        outProdDto.setSubtotal(BigDecimalUtil.formatTwoPoint(new BigDecimal(params.getSubtotal().toString())));
        ops.put(outProdDto.getPid(), JSON.toJSONString(outProdDto));
        return new ResponseResult<>(CodeStatus.OK, "修改成功");
    }

    /**
     * 删除购物车商品
     *
     * @param params
     * @param prefix
     * @return
     */
    public ResponseResult<Void> deleteProd(StockProdParams<OutProdDto> params, String prefix) {
        String redisKey = getRedisKey(params, prefix);
        if (redisKey.startsWith("参数错误")) {
            return new ResponseResult<>(CodeStatus.ILLEGAL_REQUEST, redisKey);
        }
        redisTemplate.opsForHash().delete(redisKey, params.getPid());
        return new ResponseResult<>(CodeStatus.OK, "删除成功");
    }

    /**
     * 清空购物车
     *
     * @param params
     * @param prefix
     * @return
     */
    public ResponseResult<Void> deleteAll(StockProdParams<OutProdDto> params, String prefix) {
        String redisKey = getRedisKey(params, prefix);
        if (redisKey.startsWith("参数错误")) {
            return new ResponseResult<>(CodeStatus.ILLEGAL_REQUEST, redisKey);
        }
        redisTemplate.delete(redisKey);
        return new ResponseResult<>(CodeStatus.OK, "删除成功");
    }

    /**
     * 获取redisKey
     * 新增页面 key对应 用户id，编辑页面key对应 单据id
     * 销售出库 key前缀为 SALE_OUT，采购退货出库 key前缀为 BACK_OUT
     *
     * @param params
     * @param prefix
     * @return
     */
    private String getRedisKey(StockProdParams<OutProdDto> params, String prefix) {
        Object id = null;
        if (params.getStatus().equals(StockConstant.INSERT)) {
            if (params.getUserId() == null) {
                return "参数错误：新增页面请传递用户id";
            }
            id = params.getUserId();
        } else if (params.getStatus().equals(StockConstant.UPDATE)) {
            if (StringUtils.isBlank(params.getId())) {
                return "参数错误：编辑页面请传递单据id";
            }
            id = params.getId();
        }
        return prefix + id;
    }
}
